/************************************************************************
 * @file AbstractLogCommand.h
 * @author Ian Chen
 * @version 1.0
 * 
 * @section LICENSE
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details at
 * http://www.gnu.org/licenses/lgpl.html
 ************************************************************************/

#ifndef LOG_COMMAND_H
#define LOG_COMMAND_H

#include <plugin/command/AbstractCommand.h>
#include <plugin/service/LoggerService.h>

namespace antu
{
namespace plugin
{

/**
 * @brief The AbstractLogCommand class is used for abstraction of
 *        system-wise loggers.
 *
 * A plugin system should implement this command and set it to Framework plugin's
 * singleton object for all other plugins to use logging in the system.
 */
class AbstractLogCommand : public AbstractCommand
{
private:
    LoggerService::LogType m_eLogType;

public:
    /**
     * @brief AbstractLogCommand's default constructor.
     */
    AbstractLogCommand();

protected:
    /**
     * @brief Execution logic for the logger
     * @param context Command context.
     * @param inputs Inputs to the logger command.
     * @param outputs Outputs from the logger command, in the logger command case, this field
     *                is not used.
     * @return Indication of command execution.
     */
    virtual AbstractCommand::CommandReturnType executeCommand(CommandParameters& context, const CommandParameters& inputs, CommandParameters& outputs);

public:
    virtual void init() = 0;

public:

    /**
     * @brief Logs a message.
     * @param type Type of the log message, default values are: DEBUG/INFO/WARN/ERROR/FATAL.
     * @param fileName Name of the source code file that generated the log message.
     * @param line Line of the code where the log message is generated.
     * @param className Name of the class that generated this message.
     * @param methodName Name of the method that generated the message.
     * @param message Message itself.
     */
    void log(LoggerService::LogType type, const QString& fileName, int line, const QString& className, const QString& methodName, const QString& message);

    /**
     * @brief Logs a DEBUG level message.
     * @param fileName Name of the source code file that generated the log message.
     * @param line Line of the code where the log message is generated.
     * @param className Name of the class that generated this message.
     * @param methodName Name of the method that generated the message.
     * @param message Message itself.
     */
    virtual void debug(const QString& fileName, int line, const QString& className, const QString& methodName, const QString& message) = 0;

    /**
     * @brief Logs a INFO level message.
     * @param fileName Name of the source code file that generated the log message.
     * @param line Line of the code where the log message is generated.
     * @param className Name of the class that generated this message.
     * @param methodName Name of the method that generated the message.
     * @param message Message itself.
     */
    virtual void info(const QString& fileName, int line, const QString& className, const QString& methodName, const QString& message) = 0;

    /**
     * @brief Logs a WARN level message.
     * @param fileName Name of the source code file that generated the log message.
     * @param line Line of the code where the log message is generated.
     * @param className Name of the class that generated this message.
     * @param methodName Name of the method that generated the message.
     * @param message Message itself.
     */
    virtual void warn(const QString& fileName, int line, const QString& className, const QString& methodName, const QString& message) = 0;

    /**
     * @brief Logs a ERROR level message.
     * @param fileName Name of the source code file that generated the log message.
     * @param line Line of the code where the log message is generated.
     * @param className Name of the class that generated this message.
     * @param methodName Name of the method that generated the message.
     * @param message Message itself.
     */
    virtual void error(const QString& fileName, int line, const QString& className, const QString& methodName, const QString& message) = 0;

    /**
     * @brief Logs a FATAL level message.
     * @param fileName Name of the source code file that generated the log message.
     * @param line Line of the code where the log message is generated.
     * @param className Name of the class that generated this message.
     * @param methodName Name of the method that generated the message.
     * @param message Message itself.
     */
    virtual void fatal(const QString& fileName, int line, const QString& className, const QString& methodName, const QString& message) = 0;

    /**
     * @brief Sets the log level of the logger.
     * @param level Level of the message to log.
     */
    virtual void setLogLevel(LoggerService::LogType level) = 0;

    /**
     * @brief Gets the log level used by current logger.
     * @return Returns the current log level.
     */
    LoggerService::LogType logLevel() const;
};

typedef shared_ptr<AbstractLogCommand> AbstractLogCommandSharedPtr;
}
}

#endif
